package com.csc.banking.filter;

import java.io.IOException;
import java.util.Properties;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.tanesha.recaptcha.ReCaptchaImpl;
import net.tanesha.recaptcha.ReCaptchaResponse;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.web.filter.OncePerRequestFilter;

public class CaptchaVerifierFilter extends OncePerRequestFilter{
	
	private CaptchaCaptureFilter captchaCaptureFilter;
	private Boolean useProxy = false;
	private String proxyPort;
	private String proxyHost;
	private String failureUrl;	
	private String privateKey;
	private SimpleUrlAuthenticationFailureHandler failureHandler = new SimpleUrlAuthenticationFailureHandler();
	static public Logger logger = LogManager.getLogger("Filter");
	@Override
	protected void doFilterInternal(HttpServletRequest req,
			HttpServletResponse res, FilterChain chain)
			throws ServletException, IOException {
		//Start Logging
		//System.out.println(logger.isInfoEnabled())
		logger.info("Captcha verifier filter");
		logger.debug("challenge: " + captchaCaptureFilter.getRecaptcha_challenge());
		logger.debug("response: " + captchaCaptureFilter.getRecaptcha_response());
		logger.debug("remoteAddr: " + captchaCaptureFilter.getRemoteAddr());
		//Captcha response
		if (captchaCaptureFilter.getRecaptcha_response() != null) {
			ReCaptchaImpl reCaptcha = new ReCaptchaImpl();
			reCaptcha.setPrivateKey(privateKey);
			// Assign proxy if needed
			if (useProxy) {
			    Properties systemSettings = System.getProperties();
			    systemSettings.put("http.proxyPort",proxyPort);     
			    systemSettings.put("http.proxyHost",proxyHost);
			}
			//Send HTTP request to validate user's Captcha
			ReCaptchaResponse reCaptchaResponse = reCaptcha.checkAnswer(
					captchaCaptureFilter.getRemoteAddr(), 
					captchaCaptureFilter.getRecaptcha_challenge(), 
					captchaCaptureFilter.getRecaptcha_response());
			 if (!reCaptchaResponse.isValid()) {				 
				 logger.debug("Captcha is Invalid!");
				 //Redirect to login page
				 failureHandler.setDefaultFailureUrl(failureUrl);
				 failureHandler.onAuthenticationFailure(req, res, new BadCredentialsException("Captcha invalid!"));
			 }else{
				 logger.debug("Captcha is Valid!");				 
			 }
			 //Reset captcha field after processing. This is a important thing!
			 resetCaptchaFields();
		}
		//Process other filters (if any)
		chain.doFilter(req, res);
	}
	/** 
	  * Reset Captcha fields
	  */
	 public void resetCaptchaFields() {
	  captchaCaptureFilter.setRemoteAddr(null);
	  captchaCaptureFilter.setRecaptcha_challenge(null);
	  captchaCaptureFilter.setRecaptcha_response(null);
	 }
	public CaptchaCaptureFilter getCaptchaCaptureFilter() {
		return captchaCaptureFilter;
	}
	public void setCaptchaCaptureFilter(CaptchaCaptureFilter captchaCaptureFilter) {
		this.captchaCaptureFilter = captchaCaptureFilter;
	}
	public Boolean getUseProxy() {
		return useProxy;
	}
	public void setUseProxy(Boolean useProxy) {
		this.useProxy = useProxy;
	}
	public String getProxyPort() {
		return proxyPort;
	}
	public void setProxyPort(String proxyPort) {
		this.proxyPort = proxyPort;
	}
	public String getProxyHost() {
		return proxyHost;
	}
	public void setProxyHost(String proxyHost) {
		this.proxyHost = proxyHost;
	}
	public String getFailureUrl() {
		return failureUrl;
	}
	public void setFailureUrl(String failureUrl) {
		this.failureUrl = failureUrl;
	}
	public String getPrivateKey() {
		return privateKey;
	}
	public void setPrivateKey(String privateKey) {
		this.privateKey = privateKey;
	}
	public SimpleUrlAuthenticationFailureHandler getFailureHandler() {
		return failureHandler;
	}
	public void setFailureHandler(
			SimpleUrlAuthenticationFailureHandler failureHandler) {
		this.failureHandler = failureHandler;
	}
	 
}
